﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using YmtAuth.Common.Utility;
using YmtAuth.Domain.Shard;
using YmtAuth.Common.Extend;
using MongoDB.Driver.Builders;
using MongoDB.Driver;
using MongoDB.Bson;
using System.Configuration;
using System.Text.RegularExpressions;
using YmtAuth.Domain.Model.BlacklistUser;

namespace YmtAuth.Domain.Model.LoginAuth
{
    /// <summary>
    /// 用户登录凭证规格
    /// </summary>
    public static class UserLoginAuthSpecifications
    {
        /// <summary>
        /// 认证规格
        /// </summary>        
        public static IMongoQuery MatchLoginKey2(string ukey, string password)
        {
            var _tmpKey = ukey.Trim().ToLower();
            var mobilePattern = ConfigurationManager.AppSettings["mobilematch"];
            var emialPattern = ConfigurationManager.AppSettings["emailmatch"];
            var encryptPassword = new Encrypt().EncryptUserPassword(password);
            var query = Query.Null;
            if (_tmpKey.IsMail(emialPattern))
            {               
                query = Query.And(Query<UserLoginBill>.EQ(e => e.LoginBills.Email, _tmpKey)
                                , Query<UserLoginBill>.EQ(e => e.LoginPassword, encryptPassword));
            }
            else if (_tmpKey.StartsWith("+") || _tmpKey._IsMobile(mobilePattern))//手机如果带+符号，直接匹配手机字段登录
            {
                query = Query.And(Query<UserLoginBill>.EQ(e => e.LoginBills.Mobile, _tmpKey)
                                , Query<UserLoginBill>.EQ(e => e.LoginPassword, encryptPassword));
            }
            else
            {               
                query = Query.And(Query<UserLoginBill>.EQ(e => e.LoginBills.LoginId, _tmpKey)
                                , Query<UserLoginBill>.EQ(e => e.LoginPassword, encryptPassword));
            }

            return query;
        }
        public static bool IsLoginId(string loginKey)
        {
            var _tmpKey = loginKey.Trim().ToLower();
            var mobilePattern = ConfigurationManager.AppSettings["mobilematch"];
            var emialPattern = ConfigurationManager.AppSettings["emailmatch"];

            return !_tmpKey.IsMail(emialPattern) && !_tmpKey._IsMobile(mobilePattern);
        }

        public static IMongoQuery MatchLoginKey(string loginId)
        {
            var lowerLoginKey = loginId.Trim().ToLower();
            var mobilePattern = ConfigurationManager.AppSettings["mobilematch"];
            var emialPattern = ConfigurationManager.AppSettings["emailmatch"];
            var sellerMobilePattern = ConfigurationManager.AppSettings["sellermobilematch"] ?? @"^\d*\+{0,1}\d*$";
            var query = Query.Null;
            if (lowerLoginKey.Contains("@") || lowerLoginKey.IsMail(emialPattern))
            {
                query = Query.EQ("lBills.Email", lowerLoginKey);
            }
            else if (Regex.IsMatch(lowerLoginKey, sellerMobilePattern, RegexOptions.IgnoreCase) || lowerLoginKey._IsMobile(mobilePattern))//手机如果带+符号，直接匹配手机字段登录
            {
                query = Query.EQ("lBills.Mobile", lowerLoginKey);
            }
            else
            {
                query = Query.EQ("lBills.LoginId", lowerLoginKey);
            }
            return query;
        }
        [Obsolete("use MatchLoginKey(string loginId)",true)]
        public static IMongoQuery MatchLoginKey(string loginKey, string pas)
        {
            var encryptPassword = new Encrypt().EncryptUserPassword(pas);
            var lowerLoginKey = loginKey.ToLower();
            
            return Query.And(Query<UserLoginBill>.EQ(e => e.LoginPassword, encryptPassword)
                  , Query.Or(Query<UserLoginBill>.EQ(e => e.LoginBills.LoginId, lowerLoginKey)
                           , Query<UserLoginBill>.EQ(e => e.LoginBills.Mobile, lowerLoginKey)
                           , Query<UserLoginBill>.EQ(e => e.LoginBills.Email, lowerLoginKey)));
        }
        /// <summary>
        /// 匹配用户ID
        /// </summary>
        /// <param name="userId"></param>
        /// <returns></returns>
        //public static IMongoQuery MatchUserId(int userId)
        //{
        //    return Query<UserLoginBill>.EQ(e => e.UserId, userId);
        //}

        public static IMongoQuery MatchUserId(int userId)
        {
            return Query<UserLoginBill>.EQ(e => e.UserId, userId);
            //.Where(e => e.UserId == userId);
        }
        /// <summary>
        /// 匹配登录用户userID
        /// </summary>
        /// <param name="userId"></param>
        /// <returns></returns>
        public static Expression<Func<UserLoginBill, bool>> MatchLoginUserId(int userId)
        {
            return e => e.UserId == userId;
        }
        /// <summary>
        /// 验证客户端请求key 是否不合法。  
        /// <remarks>true 不合法</remarks>
        /// </summary>           
        public static Expression<Func<bool>> VerifyRequest(string loginKey, string password)
        {
            return () => string.IsNullOrEmpty(loginKey);
        }
        /// <summary>
        /// 匹配登录ID
        /// </summary>
        /// <param name="loginId"></param>
        /// <returns></returns>
        public static IMongoQuery MatchLoginId(string loginId)
        {
            var _loginId = loginId.ToLower().Trim();
            //return Query<UserLoginBill>.Where(e => e.LoginBills.LoginId == _loginId);
            return Query<UserLoginBill>.EQ(e => e.LoginBills.LoginId, _loginId);
        }

        /// <summary>
        /// 匹配登录ID
        /// </summary>
        /// <param name="loginId"></param>
        /// <returns></returns>
        public static IMongoQuery MatchLoginId(string loginId, bool lowerCase)
        {
            string _loginId = loginId;
            if(lowerCase && !string.IsNullOrEmpty(loginId))
            {
                _loginId = loginId.ToLower().Trim(); 
            }
            
            return Query<UserLoginBill>.EQ(e => e.LoginBills.LoginId, _loginId);
        }

        /// <summary>
        /// 反向匹配loginId 是否被非当前用户使用
        /// </summary>
        /// <param name="loginId"></param>
        /// <param name="userId"></param>
        /// <returns></returns>
        public static IMongoQuery NotMatchLoginIdByUserId(string loginId, int userId)
        {
            var _loginId = loginId.ToLower();
            //return Query<UserLoginBill>.Where(e => e.LoginBills.LoginId == _loginId
            //                                    && e.UserId != userId);
            return Query.And(Query<UserLoginBill>.EQ(e => e.LoginBills.LoginId, _loginId)
                , Query.Not(Query<UserLoginBill>.EQ(e => e.UserId, userId)));
        }
        /// <summary>
        /// 反向匹配Mobile 是否被非当前用户使用
        /// </summary>
        /// <param name="loginId"></param>
        /// <param name="userId"></param>
        /// <returns></returns>
        public static IMongoQuery NotMatchLoginMobileByUserId(string mobile, int userId)
        {
            return Query.And(Query<UserLoginBill>.EQ(e => e.LoginBills.Mobile, mobile)
                , Query.Not(Query<UserLoginBill>.EQ(e => e.UserId, userId)));
        }
        /// <summary>
        /// 反向匹配loginMail 是否被非当前用户使用
        /// </summary>
        /// <param name="loginId"></param>
        /// <param name="userId"></param>
        /// <returns></returns>
        public static IMongoQuery NotMatchLoginMailByUserId(string loginMail, int userId)
        {
            var _loginEmail = loginMail.ToLower();
            //return Query<UserLoginBill>.Where(e => e.LoginBills.Email == _loginEmail
            //                                    && e.UserId != userId);
            return Query.And(Query<UserLoginBill>.EQ(e => e.LoginBills.Email, _loginEmail)
                , Query.Not(Query<UserLoginBill>.EQ(e => e.UserId, userId)));
        }
        public static IMongoQuery MatchLoginIdByImport(string loginId)
        {
            var _loginId = loginId.ToLower();
            //return Query<UserLoginBill>.Where(e => e.LoginBills.LoginId == _loginId);
            return Query<UserLoginBill>.EQ(e => e.LoginBills.LoginId, _loginId);
        }
        /// <summary>
        /// 匹配登录手机
        /// </summary>
        /// <param name="mobile"></param>
        /// <returns></returns>
        public static IMongoQuery MatchLoginMobile(string mobile)
        {
            return Query<UserLoginBill>.EQ(e => e.LoginBills.Mobile, mobile);
        }
        public static IMongoQuery MathLoginMobileArray(IEnumerable<string> mobile)
        {
            return Query<UserLoginBill>.In(e => e.LoginBills.Mobile, mobile);
        }
        public static IMongoQuery MathUserIdArray(IEnumerable<int> userId)
        {
            return Query<UserLoginBill>.In(e => e.UserId, userId);
        }
        /// <summary>
        /// 匹配登录登录邮箱 （不区分大小写）
        /// </summary>
        /// <param name="email"></param>
        /// <returns></returns>
        public static IMongoQuery MatchLoginMail(string email)
        {
            var _email = email.ToLower();
            //return Query<UserLoginBill>.Where(e => e.LoginBills.Email == _email);
            return Query<UserLoginBill>.EQ(e => e.LoginBills.Email, _email);
        }
        /// <summary>
        /// 匹配全部
        /// </summary>
        /// <returns></returns>
        public static IMongoQuery MatchAll()
        {
            return Query.Null;
        }
        public static UpdateBuilder<UserLoginBill> UpateUserToken(string token)
        {
            return Update<UserLoginBill>.Combine(Update<UserLoginBill>.Set(e => e.Token, token), Update<UserLoginBill>.Set(e => e.ModifyDate, DateTime.Now));
        }
        public static UpdateBuilder<UserLoginBill> UpdateUserTradingPassword(string pas)
        {
            return Update<UserLoginBill>.Combine(Update<UserLoginBill>.Set(e => e.TradingPassword, pas), Update<UserLoginBill>.Set(e => e.ModifyDate, DateTime.Now));
        }
        public static UpdateBuilder<UserLoginBill> UpdateUserLoginPassword(string pas)
        {
            return Update<UserLoginBill>.Combine(Update<UserLoginBill>.Set(e => e.LoginPassword, pas), Update<UserLoginBill>.Set(e => e.ModifyDate, DateTime.Now));
        }
        public static UpdateBuilder<UserLoginBill> UpateUserMobile(string mobile)
        {
            return Update<UserLoginBill>.Set(e => e.LoginBills.Mobile, mobile);
        }
        public static UpdateBuilder<UserLoginBill> UpateUserEmail(string email)
        {
            return Update<UserLoginBill>.Set(e => e.LoginBills.Email, email);
        }
        public static UpdateBuilder<UserLoginBill> UpateUserLoginIdOrEmail(string email, string loginId)
        {
            var update = Update<UserLoginBill>.Combine(Update<UserLoginBill>.Set(e => e.LoginBills.LoginId, loginId.ToLower())
                , Update<UserLoginBill>.Set(e => e.ModifyDate, DateTime.Now));
            if (!string.IsNullOrEmpty(email))
                return update.Combine(Update<UserLoginBill>.Set(e => e.LoginBills.Email, email.ToLower()));
            return update;
        }
        public static UpdateBuilder<UserLoginBill> UpateUserLoginPassword(string pas)
        {
            return Update<UserLoginBill>.Set(e => e.LoginPassword, pas);
        }
        public static UpdateBuilder<UserLoginBill> SetLocked()
        {
            return Update<UserLoginBill>.Set(e => e.Locked, true);
        }
        public static UpdateBuilder<UserLoginBill> SetUnLocked()
        {
            return Update<UserLoginBill>.Set(e => e.Locked, false);
        }
        //检查买手登陆是否禁用邮箱登陆 
        public static bool CheckSellerLoginDisableEmail(string loginId, string source)
        {
            if (!YmatouBlacklistUserSpecifications.IsSellerSource(source)) return false;
            var emialPattern = ConfigurationManager.AppSettings["emailmatch"];
            var disable = ConfigurationManager.AppSettings["Disable_Seller_LoginMail"];
            return disable == "1" && loginId.IsMail(emialPattern);
        }

        public static string GetDisableSellerEmailResMessage()
        {
            return ConfigurationManager.AppSettings["Disable_Seller_LoginMail_ResTips"]
                ?? "邮箱禁止登录,请使用手机或用户名登录";
        }
    }
}
